package caro.client.gui;

import caro.app.bussiness.ClientUtil;
import caro.app.bussiness.UserSession;
import caro.client.gui.templates.AbstractWindow;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.WindowListener;
import java.util.*;
import javax.swing.*;
import java.net.*;
/**
 * Class MainInterface
 * @author Thanh Nhan
 * @Since Aug 28, 2011
 * @Version 1.0
 */
public class MainInterface extends AbstractWindow{
    
    private List<String> freeUser = null;
    private List<String> busyUser = null;
    private UserSession session = null;
    private Socket s = null;
    
    private JList listUsers = null;
    private JLabel board[][] = null;
    private JLabel myPawn;
    private JLabel myPawnIcon;
    private JLabel opponentInfo;
    private JLabel playsInfo;
    JTextArea chatContent;
    JTextField chatInput;
    
    public static final String BUSY_STRING = Messages.getString("busy");
    public static final String BUSY_END_STRING = ")";
    public static final int R = 20,C = 15;
    
    public MainInterface(UserSession userSession, Socket s,List<String> freeUser, List<String> busyUser){
        this.session = userSession;
        this.s = s;
        this.freeUser = freeUser;
        this.busyUser = busyUser;
        WIN_W = 1000;
        WIN_H = 500;
        setTitle(Messages.getString("appTitle") + "-" + session.getMyUsername());
        setSize(WIN_W, WIN_H);
        setLocationRelativeTo(null);
        setLayout(null);
        //Title component
        JLabel bgTitle = new JLabel(ImageProvider.getInstance().getImage("backgroundTitle.png"));
        bgTitle.setHorizontalAlignment(JLabel.LEFT);
        bgTitle.setLayout(null);
        
        JLabel title = new JLabel(Messages.getString("appTitle"));
        title.setFont(new Font("Arial", Font.BOLD + Font.ITALIC, 20));
        title.setForeground(new Color(19, 58, 10));
        title.setBounds((WIN_W - CELL_W*9)/2, 0, CELL_W*9, CELL_H);
        
        JLabel subTitle = new JLabel(Messages.getString("mainBoard"));
        subTitle.setFont(new Font("Arial", Font.BOLD, 13));
        subTitle.setForeground(new Color(19, 58, 10));
        subTitle.setBounds(WIN_W - CELL_W*21, BORDER_H + CELL_H, CELL_W*11, CELL_H);
        
        bgTitle.setBounds(0, 0, WIN_W, 50);
        bgTitle.add(title);
        bgTitle.add(subTitle);
        
        //List users
        
        listUsers = new JList(getListUsers(busyUser, freeUser));
        JScrollPane scroll = new JScrollPane(listUsers);
        scroll.setBorder(BorderFactory.createMatteBorder(0, 1, 5, 1, new Color(47, 200, 39)));
        JPanel listUserPn = new JPanel(new BorderLayout());
        listUserPn.setBounds(BORDER_W, BORDER_H + bgTitle.getHeight() + BORDER_H, 8*CELL_W, 8*CELL_H);
        listUserPn.add(scroll, BorderLayout.CENTER);
        JLabel listLb = new JLabel(Messages.getString("listUsersLabel"), ImageProvider.getInstance().getImage("icon.png"), JLabel.LEFT);
        listLb.setOpaque(true);
        listLb.setBackground(new Color(47, 200, 39));
        listLb.setBorder(BorderFactory.createMatteBorder(5, 0, 5, 0, new Color(47, 200, 39)));
        listUserPn.add(listLb, BorderLayout.PAGE_START);
        add(bgTitle);
        add(listUserPn);
        
        //Board
        board = new JLabel[R][C];
        JPanel boardPn = new JPanel(null);
        boardPn.setBounds(BORDER_W + listUserPn.getWidth() + CELL_W
                , BORDER_H + bgTitle.getHeight() + BORDER_H, R*CELL_W, C*CELL_H);
        //boardPn.setBackground(new Color(47, 160, 39));
        
        for(int i = 0; i < R; i++)
            for(int j = 0; j < C; j++){
                board[i][j] = new JLabel(ImageProvider.getInstance().getImage("bgCell.png"));
                board[i][j].setName(String.valueOf(i).concat(String.valueOf(j)));
                board[i][j].setBackground(Color.BLACK);
                if(i == R - 1 && j == C - 1)
                    board[i][j].setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, new Color(47, 160, 39)));
                else if(j == C - 1)
                    board[i][j].setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, new Color(47, 160, 39)));
                else if(i == R - 1)
                    board[i][j].setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, new Color(47, 160, 39)));
                
                else
                    board[i][j].setBorder(BorderFactory.createMatteBorder(1, 1, 0, 0, new Color(47, 160, 39)));
                board[i][j].setBounds(i*(CELL_W), j*(CELL_H), CELL_W, CELL_H);
                boardPn.add(board[i][j]);
            }
        add(boardPn);
        //Chat component
        chatContent = new JTextArea(19, 20);
        JScrollPane scrollChat = new JScrollPane(chatContent);
        scrollChat.setBorder(null);
        chatInput = new JTextField();
        chatInput.setBorder(BorderFactory.createMatteBorder(10, 0, 10, 0, Color.WHITE));
        chatInput.setFont(new Font("Arial", Font.ITALIC, 15));
        JPanel chatPnParent = new JPanel(new BorderLayout());
        JPanel chatPn = new JPanel();
        JSplitPane chatContentSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, scrollChat, chatInput);
        chatContentSplit.setDividerSize(2);
        
        chatPn.add(chatContentSplit);
        chatPnParent.setBounds(BORDER_W + boardPn.getX() + boardPn.getWidth()
                , BORDER_H + bgTitle.getHeight() + BORDER_H, 10*CELL_W, C*CELL_H);
        
        JLabel chatLb = new JLabel(Messages.getString("chatLabel"), ImageProvider.getInstance().getImage("icon.png"), JLabel.LEFT);
        chatLb.setOpaque(true);
        chatLb.setBackground(new Color(47, 200, 39));
        chatLb.setBorder(BorderFactory.createMatteBorder(5, 0, 5, 0, new Color(47, 200, 39)));
        chatPn.setBounds(0
                , BORDER_H + bgTitle.getHeight() + BORDER_H, 10*CELL_W, (C-2)*CELL_H);
        chatPnParent.add(chatLb, BorderLayout.PAGE_START);
        chatPnParent.add(chatPn, BorderLayout.CENTER);
        add(chatPnParent);
        
        //Session info component
        JPanel sessionInfoPn = new JPanel(new BorderLayout());
        sessionInfoPn.setBounds(BORDER_W, listUserPn.getY() + listUserPn.getHeight() + BORDER_H, 8*CELL_W, 7*CELL_H);
        JLabel sessionInfoLb = new JLabel(Messages.getString("sessionUserLabel"), ImageProvider.getInstance().getImage("icon.png"), JLabel.LEFT);
        sessionInfoLb.setOpaque(true);
        sessionInfoLb.setBackground(new Color(47, 200, 39));
        sessionInfoLb.setBorder(BorderFactory.createMatteBorder(5, 0, 5, 0, new Color(47, 200, 39)));
        sessionInfoPn.add(sessionInfoLb, BorderLayout.PAGE_START);
        
        JPanel sessionContentPn = new JPanel(null);
        
        myPawn = new JLabel(Messages.getString("mypawn"));
        myPawn.setOpaque(true);
        myPawn.setBounds(BORDER_W, BORDER_H, 5*CELL_W, CELL_H);
        myPawnIcon = new JLabel();
        myPawnIcon.setOpaque(true);
        myPawnIcon.setBounds(BORDER_W + myPawn.getWidth() + BORDER_W, BORDER_H, 2*CELL_W, CELL_H);
        opponentInfo = new JLabel(Messages.getString("opponentInfo"));
        opponentInfo.setBounds(BORDER_W, BORDER_H + myPawn.getHeight() + BORDER_H, 7*CELL_W, CELL_H);
        playsInfo = new JLabel(Messages.getString("playsInfo"));
        playsInfo.setBounds(BORDER_W, BORDER_H + opponentInfo.getY() + opponentInfo.getHeight() + BORDER_H, 7*CELL_W, CELL_H);
        
        sessionContentPn.add(myPawn);
        sessionContentPn.add(myPawnIcon);
        sessionContentPn.add(opponentInfo);
        sessionContentPn.add(playsInfo);
        sessionContentPn.setBorder(BorderFactory.createMatteBorder(0, 1, 5, 1, new Color(47, 200, 39)));
        sessionInfoPn.add(sessionContentPn, BorderLayout.CENTER);
        add(sessionInfoPn);
        
        makeChatContentReadOnly();
        setDisableChatInput();
    }
    private void makeChatContentReadOnly(){
        chatContent.setEditable(false);
    }
    public void setEnableChatInput(){
        chatInput.setEditable(true);
    }
    public void setDisableChatInput(){
        chatInput.setEditable(false);
    }
    public void setSessionInfo(String opponentName, int currentValue){
        myPawnIcon.setIcon((Icon)ClientUtil.getInstance().getPawnDisplay(currentValue));
        opponentInfo.setText(opponentInfo.getText().concat(" ").concat(opponentName));
    }
    public void setPlaysInfo(String userName){
        String text = playsInfo.getText();
        text = text.substring(0, text.lastIndexOf(" "));
        playsInfo.setText(text.concat(" ").concat(userName));
    }
    public UserSession getUserSession(){
        return session;
    }
    public void clearUserInfo(){
        myPawnIcon.setIcon(null);
        myPawn.setText(Messages.getString("mypawn"));
        playsInfo.setText(Messages.getString("playsInfo"));
        opponentInfo.setText(Messages.getString("opponentInfo"));
    }
    public void clearSession(){
        session = new UserSession(session.getMyUsername());
    }
    public void clearBoard(){
        for(int i= 0 ; i < R; i++)
            for(int j = 0; j < C; j++){
                board[i][j].setIcon(null);
            }
    }
    private Object[] getListUsers(List<String> busy, List<String> free){
        List<String> rs = new ArrayList<String>();
        for(String username: free){
            
            rs.add(username);
            
        }
        for(String username: busy){
            
            rs.add(username.concat(BUSY_STRING));
            
        }
        Collections.sort(rs);
        return rs.toArray();
    }
    private void updateListUsers(){
        listUsers.setListData(getListUsers(busyUser, freeUser));
    }
    public void removeFree(String username){
        freeUser.remove(username);
        busyUser.add(username);
        updateListUsers();
    }
    public void removeBusy(String username){
        busyUser.remove(username);
        freeUser.add(username);
        updateListUsers();
    }
    public void addFree(String username){
        freeUser.add(username);
        busyUser.remove(username);
        updateListUsers();
    }
    public void addBusy(String username){
        busyUser.add(username);
        freeUser.remove(username);
        updateListUsers();
    }
    public void removeUser(String username){
        busyUser.remove(username);
        freeUser.remove(username);
        updateListUsers();
    }

    /**
     * @return the socket
     */
    public Socket getSocket() {
        return s;
    }
    
    public JList getListUser(){
        return listUsers;
    }
    
    public JLabel[][] getBoard(){
        return board;
    }
    
    public String getChatInput(){
        return chatInput.getText();
    }
    public void setChatInput(String text){
        chatInput.setText(text);
    }
    
    public void setTextContent(String text, String username){
        chatContent.setText(chatContent.getText().concat("\n"));
        chatContent.setText(chatContent.getText().concat(username).concat(": ").concat(text));
    }
    
    public String getSelectedUser(){
        return listUsers.getSelectedValue().toString();
    }
    
    public void disableBoard(MouseListener action){
        for(int i = 0; i < R; i++)
            for(int j = 0; j < C; j++){
                board[i][j].removeMouseListener(action);
            }
    }
    
    public void enableBoard(MouseListener action){
        for(int i = 0; i < R; i++)
            for(int j = 0; j < C; j++){
                board[i][j].addMouseListener(action);
            }
    }
    
    //Listeners
    public void addUsersListListener(MouseListener action){
        listUsers.addMouseListener(action);
    }
    public void addBoardListener(MouseListener action){
        for(int i = 0; i < R; i++)
            for(int j = 0; j < C; j++){
                board[i][j].addMouseListener(action);
            }
    }
    public void addChatListener(KeyListener listen){
        chatInput.addKeyListener(listen);
    }
}
